// 供全局使用
let h;

// 支持的类型
const cascaderType = ["el-cascader", "el-cascader-panel"];

export default {
  name: "SCascader",
  // $attrs中的成员不显示在dom上
  inheritAttrs: false,
  model: {
    prop: "value",
    event: "dataChange",
  },
  props: {
    // 类型
    type: {
      default: "el-cascader",
      validator: (typeVal) => {
        return cascaderType.includes(typeVal);
      },
    },
    props: {
      type: Object,
      default: () => {
        return {
          children: "children",
          label: "label",
          value: "value",
          checkStrictly: false,
        };
      },
    },
    // 绑定值
    value: [String, Number],
    // 备选项
    options: {
      type: Array,
      default: () => [],
    },
    dataRequest: Function,
    requestOption: Object,
    // 引用el-cascader的ref名称
    refName: String,

    // 支持el-cascader/el-cascader-panel所有参数
  },
  mounted() {
    this.init();
  },
  data() {
    return {
      newOptions: this.options,
      newValue: [],
    };
  },
  watch: {
    requestOption: {
      async handler(requestOption) {
        this.newOptions = await this.dataRequest({
          ...requestOption,
        });
      },
    },
    value(value) {
      value ?? (this.newValue = []);
    },
  },
  methods: {
    getFathersById(id, data, prop = "id") {
      var arrRes = [];
      const rev = (data, nodeId) => {
        for (var i = 0, length = data.length; i < length; i++) {
          const node = data[i];
          if (node[prop] === nodeId) {
            arrRes.unshift(node[prop]);
            return true;
          } else {
            if (node.descendants && node.descendants.length) {
              if (rev(node.descendants, nodeId)) {
                arrRes.unshift(node[prop]);
                return true;
              }
            }
          }
        }
        return false;
      };
      rev(data, id);
      return arrRes;
    },
    async init() {
      if (!this.options.length) {
        this.newOptions = await this.dataRequest({
          ...this.requestOption,
        });
      } else {
        this.newOptions = this.options;
      }

      this.newValue = this.getFathersById(
        this.value,
        this.newOptions,
        this.props.value
      );
    },
  },
  render() {
    h = this.$createElement;
    const { type, refName, $attrs, newOptions } = this;

    let cascaderVNode = h(type, {
      props: {
        value: this.newValue,
        options: newOptions,
        props: this.props,
        ...$attrs,
      },
      on: {
        ...Object.assign(
          {},
          // 添加所有的监听器
          this.$listeners,
          // 覆写一些监听器的行为
          {
            change: (event) => {
              this.newValue = event;
              this.$emit("dataChange", event[event.length - 1]);
              this.$emit("change", event[event.length - 1]);
            },
          }
        ),
      },
      ref: refName || "el-cascader",
    });

    return cascaderVNode;
  },
};
